//***************************************************************************
//   Copyright(c)2020, Xidian University D405.
//   All rights reserved
//
//   IP Name         :   Null
//   File name       :   np_dma_top.v
//   Module name     :   np_dma_top
//   Author          :   Wang Zekun
//   Date            :   2022/06/12
//   Version         :   v2.8
//   Verison History :   v1.0/v2.0/v2.1/v2.2/v2.3/v2.4/v2.5/v2.6/2.7.1/2.7.2/v2.8
//   Edited by       :   Wang Zekun
//   Modification history : v1.0 Initial revision
//                          v2.0 modify np dma structure
//                          v2.1 replace clogb2 function
//                          v2.2 modify DMA fifo parameter define,add two parameter for AXI
//                          v2.3 add interrupt mechanism
//                          v2.4 add axir_rxdesc_fifo empty mechanism
//                          v2.5 new function hdfwd model sel,delete axi stream user signals
//                          v2.6 update fifo, and valid signals of fifo. add rxfifo data empty.
//                          v2.7 add dma_data_empty_0_i, dma_data_empty_1_i ports.
//                          v2.7.1 add testmode, change parameter NP_DMA_BASE_ADDR to wire port.
//                          v2.7.2 rx_mac_int_lock should not be checked at rx processing.
//                          v2.8 details in np_dma_decode.v v2.91
// ----------------------------------------------------------------------------
// Version 2.50      Date(2022/05/05)
// Abstract : Hardforward DMA unit;send data from mac to main memory across 
//                AXI Master interface.
// Version 2.60      Date(2022/05/17) zyc
// Abstract : add rxfifo data empty, axi_sfifo -> axi_sfifo_2T
//            beat the rx_desc_fifo_rd_valid rxfifo_length_rd_valid tdesc_fifo_rd_valid,
//            replace all "parameter" inside the module with "localparam"
//-----------------------------------------------------------------------------
// Programmer's model
// Base Address 0x8FFF_0000
// 0x00 RW    [31:0]
// 0x04 RW    [31:0]
// 0x08 RW    [31:0]
// 0x0C RW    [31:0]
// 0x10 RO    [31:0]
//-----------------------------------------------------------------------------
//interface list :
//                AXI Master
//                AXI_stream*2
//                AHB
//                IRQ

module np_dma_top #	(
		// Parameters of Axi Master Bus Interface M_AXI
    // Burst Length. Supports 1, 2, 4, 8, 16, 32, 64, 128, 256 burst lengths
    //parameter integer NP_DMA_BASE_ADDR     = 32'h000F_0000,
    parameter integer MAC_USER_WIDTH       = 4,  //Width of AXI-Stream USER channel
    parameter integer AXI_BURST_LEN        = 256,
    parameter integer AXI_ID_WIDTH         = 6,
    parameter integer AXI_ADDR_WIDTH       = 40,
    parameter integer AXI_DATA_WIDTH       = 128,
    parameter integer AXI_LIB_WIDTH        = 11, //Width of Max Transmit Length(in BYTES)
    parameter integer AXI_AWUSER_WIDTH     = 0,
    parameter integer AXI_ARUSER_WIDTH     = 0,
    parameter integer AXI_WUSER_WIDTH      = 0,
    parameter integer AXI_RUSER_WIDTH      = 0,
    parameter integer AXI_BUSER_WIDTH      = 0 
	)
  (
  // Parameter
  input  wire [31:0]          dma_addr,  //NP_DMA_BASE_ADDR
  // AHB Inputs
  input  wire                 HCLK,      // AHB clock
  input  wire                 HRESETn,   // system bus reset
  input  wire                 HSEL,      // AHB peripheral select
  input  wire                 HREADY,    // AHB ready input
  input  wire  [1:0]          HTRANS,    // AHB transfer type
  input  wire  [2:0]          HSIZE,     // AHB hsize
  input  wire                 HWRITE,    // AHB hwrite
  input  wire [31:0]          HADDR,     // AHB address bus
  input  wire [31:0]          HWDATA,    // AHB write data bus
  // AHB Outputs
  output wire                 HREADYOUT, // AHB ready output to S->M mux
  output wire                 HRESP,     // AHB response
  output wire [31:0]          HRDATA,

  // AXI_stream 10G interface
  input  wire                 axi_s0_clk_i,
  input  wire                 axi_s0_resetn_i,

  input  wire                               bus0_axi_strm_rtvalid_i,
  input  wire                               bus0_axi_strm_rtlast_i,
  input  wire [ 7:0]                        bus0_axi_strm_rtkeep_i,
  input  wire [63:0]                        bus0_axi_strm_rtdata_i,
  //input  wire [MAC_USER_WIDTH-1:0]          bus0_axi_strm_rtuser_i,
  output wire                               bus0_axi_strm_rtready_o,

  output wire                               bus0_axi_strm_ttvalid_o,
  output wire                               bus0_axi_strm_ttlast_o,
  output wire [ 7:0]                        bus0_axi_strm_ttkeep_o,
  output wire [63:0]                        bus0_axi_strm_ttdata_o,
  //output wire [MAC_USER_WIDTH-1:0]          bus0_axi_strm_ttuser_o,
  input  wire                               bus0_axi_strm_ttready_i,

  // AXI_stream 40G interface
  input  wire                 axi_s1_clk_i,
  input  wire                 axi_s1_resetn_i,

  input  wire                               bus1_axi_strm_rtvalid_i,
  input  wire                               bus1_axi_strm_rtlast_i,
  input  wire [ 7:0]                        bus1_axi_strm_rtkeep_i,
  input  wire [63:0]                        bus1_axi_strm_rtdata_i,
  //input  wire [MAC_USER_WIDTH-1:0]          bus1_axi_strm_rtuser_i,
  output wire                               bus1_axi_strm_rtready_o,

  output wire                               bus1_axi_strm_ttvalid_o,
  output wire                               bus1_axi_strm_ttlast_o,
  output wire [ 7:0]                        bus1_axi_strm_ttkeep_o,
  output wire [63:0]                        bus1_axi_strm_ttdata_o,
  //output wire [MAC_USER_WIDTH-1:0]          bus1_axi_strm_ttuser_o,
  input  wire                               bus1_axi_strm_ttready_i,

  // AXI_master interface
	input  wire                           m_axi_aclk_i,
	input  wire                           m_axi_aresetn_i,

	output wire [AXI_ID_WIDTH-1 : 0]      m_axi_awid_o,
	output wire [AXI_ADDR_WIDTH-1 : 0]    m_axi_awaddr_o,
	output wire [7 : 0]                   m_axi_awlen_o,
	output wire [2 : 0]                   m_axi_awsize_o,
	output wire [1 : 0]                   m_axi_awburst_o,
	output wire                           m_axi_awlock_o,
	output wire [3 : 0]                   m_axi_awcache_o,
	output wire [2 : 0]                   m_axi_awprot_o,
	output wire [3 : 0]                   m_axi_awqos_o,
	output wire [AXI_AWUSER_WIDTH-1 : 0]  m_axi_awuser_o,
	output wire                           m_axi_awvalid_o,
	input  wire                           m_axi_awready_i,

	output wire [AXI_DATA_WIDTH-1 : 0]    m_axi_wdata_o,
	output wire [AXI_DATA_WIDTH/8-1 : 0]  m_axi_wstrb_o,
	output wire                           m_axi_wlast_o,
	output wire [AXI_WUSER_WIDTH-1 : 0]   m_axi_wuser_o,
	output wire                           m_axi_wvalid_o,
	input  wire                           m_axi_wready_i,

	input  wire [AXI_ID_WIDTH-1 : 0]      m_axi_bid_i,
	input  wire [1 : 0]                   m_axi_bresp_i,
	input  wire [AXI_BUSER_WIDTH-1 : 0]   m_axi_buser_i,
	input  wire                           m_axi_bvalid_i,
	output wire                           m_axi_bready_o,

	output wire [AXI_ID_WIDTH-1 : 0]      m_axi_arid_o,
	output wire [AXI_ADDR_WIDTH-1 : 0]    m_axi_araddr_o,
	output wire [7 : 0]                   m_axi_arlen_o,
	output wire [2 : 0]                   m_axi_arsize_o,
	output wire [1 : 0]                   m_axi_arburst_o,
	output wire                           m_axi_arlock_o,
	output wire [3 : 0]                   m_axi_arcache_o,
	output wire [2 : 0]                   m_axi_arprot_o,
	output wire [3 : 0]                   m_axi_arqos_o,
	output wire [AXI_ARUSER_WIDTH-1 : 0]  m_axi_aruser_o,
	output wire                           m_axi_arvalid_o,
	input  wire                           m_axi_arready_i,
  
	input  wire [AXI_ID_WIDTH-1 : 0]      m_axi_rid_i,
	input  wire [AXI_DATA_WIDTH-1 : 0]    m_axi_rdata_i,
	input  wire [1 : 0]                   m_axi_rresp_i,
	input  wire                           m_axi_rlast_i,
	input  wire [AXI_RUSER_WIDTH-1 : 0]   m_axi_ruser_i,
	input  wire                           m_axi_rvalid_i,
	output wire                           m_axi_rready_o,

  output wire                           np_dma_irq_o, // NP DMA transmassion irq
  
  input  wire [1:0]                     dma_channel_sel_i,

	output wire                           dma_rd_leng_en_0_o  ,
	output wire                           dma_rd_data_en_0_o  ,
	input  wire                           dma_rd_leng_vld_0_i ,
	input  wire                           dma_rd_dout_vld_0_i ,
	input  wire [ 10:0]                   dma_rd_leng_0_i     ,
	input  wire [127:0]                   dma_rd_dout_0_i     ,
	input  wire                           dma_empty_0_i       ,
  input  wire                           dma_data_empty_0_i  , //05.21 zyc
						                  
	output wire                           dma_rd_leng_en_1_o  ,
	output wire                           dma_rd_data_en_1_o  ,
	input  wire                           dma_rd_leng_vld_1_i ,
	input  wire                           dma_rd_dout_vld_1_i ,
	input  wire [ 10:0]                   dma_rd_leng_1_i     ,
	input  wire [127:0]                   dma_rd_dout_1_i     ,
  input  wire                           dma_empty_1_i       ,
  input  wire                           dma_data_empty_1_i  , //05.21 zyc

  input  wire [11 : 0]                  ram_dp_cfg_register,
  input  wire [9 : 0]                   ram_2p_cfg_register,
  input  wire [6 : 0]                   rf_2p_cfg_register,

  input  wire                           testmode,
  input  wire                           mbist_test
);

  function integer clogb2 (input integer bit_depth);              
    begin:bit_width_calc
        integer bit_depth_tmp;    
        bit_depth_tmp = bit_depth;                                         
        for(clogb2=0; bit_depth_tmp>0; clogb2=clogb2+1)                   
            bit_depth_tmp = bit_depth_tmp >> 1;                                 
    end                                                           
  endfunction
  //parameter integer AXI_UNALIGN_ADDR_EN  = 0;
  localparam integer MAX_OUTSTANDING_NUM  = 32; //JUST FOR CALCULATE THE FIFO DEPTH, the actual max Outstanding Number is limited by AXI Slave.
  localparam integer MAC_DATA_WIDTH       = 64; //Width of AXI-Stream which comes from MAC
  localparam integer MAC_KEEP_WIDTH       = MAC_DATA_WIDTH/8;
  localparam integer MAC_KEEP_CNT_WIDTH   = clogb2(MAC_DATA_WIDTH/8)-1;

  localparam integer DMA_DATA_WIDTH       = 128; //Width of AXI-Full DATA WIDTH
  localparam integer DMA_LENG_WIDTH       = 11;  //-- original clogb2(1536)+1; //Width of transaction length counter

  localparam integer DMA_DESC_FIFO_rd_AW  = 6; //64
  localparam integer DMA_DESC_FIFO_wr_AW  = 6; //64

  localparam integer DMA_LENG_FIFO_rx_10g_AW  = 10;  //1024
  localparam integer DMA_DATA_FIFO_rx_10g_AW  = 12;  //4096
  localparam integer DMA_LENG_FIFO_rx_40g_AW  = 12;  //4096
  localparam integer DMA_DATA_FIFO_rx_40g_AW  = 14;  //16384

  localparam integer DMA_LENG_FIFO_tx_10g_AW  = 9;   //512
  localparam integer DMA_DATA_FIFO_tx_10g_AW  = 11;  //2048
  localparam integer DMA_LENG_FIFO_tx_40g_AW  = 7;   //128
  localparam integer DMA_DATA_FIFO_tx_40g_AW  = 9;   //512

  localparam integer DMA_DESC_FIFO_AW     = clogb2(128)-1;
  localparam integer DMA_DATA_FIFO_AW     = clogb2((1536*MAX_OUTSTANDING_NUM)/(DMA_DATA_WIDTH/8)); //Address width of RxFIFO\TxFIFO data
  localparam integer DMA_LENG_FIFO_AW     = clogb2(MAX_OUTSTANDING_NUM);

  //******  [External Ports] Wirte Channel  ******//
  wire [AXI_ID_WIDTH-1 : 0]     write_id;
  wire [AXI_ADDR_WIDTH-1 : 0]   axi_aw_addr;
  wire [AXI_LIB_WIDTH-1: 0]     axi_w_bytes;
  wire                          axi_aw_start;
  wire                          axi_write_desc_type;
  wire                          axi_write_desc_start;
  wire                          write_data_ready;
  wire                          write_desc_ready;

  //******  [External Ports] Read Channel  ******//
  wire [AXI_ID_WIDTH-1 : 0]     read_id;
  wire [AXI_ADDR_WIDTH-1 : 0]   axi_ar_addr;
  wire [AXI_LIB_WIDTH-1: 0]     axi_r_bytes;
  wire                          axi_ar_start;
  wire                          axi_read_desc_type;
  wire                          axi_read_desc_start;
  wire                          read_ready;

  wire [2:0]                    debug_state;

  //RxFIFO0 Control Signals
  wire                          rxfifo_leng0_rd_en;
  wire [AXI_LIB_WIDTH-1 : 0]    rxfifo_leng0_dout;
  wire                          rxfifo_data0_rd_en;
  wire [AXI_DATA_WIDTH-1 : 0]   rxfifo_data0_dout;
  wire                          rxfifo_empty0;

  //RxFIFO1 Control Signals
  wire                          rxfifo_leng1_rd_en;
  wire [AXI_LIB_WIDTH-1 : 0]    rxfifo_leng1_dout;
  wire                          rxfifo_data1_rd_en;
  wire [AXI_DATA_WIDTH-1 : 0]   rxfifo_data1_dout;
  wire                          rxfifo_empty1;

  //RxFIFO Control after mux Signals
  wire                          rxfifo_leng_rd_en;
  wire [AXI_LIB_WIDTH-1 : 0]    rxfifo_leng_dout;
  wire                          rxfifo_data_rd_en;
  wire [AXI_DATA_WIDTH-1 : 0]   rxfifo_data_dout;
  wire                          rxfifo_data_valid;
  wire                          rxfifo_empty;

  wire                          rx_port_sel;
  wire                          tx_port_sel;

  //TxFIFO Control Signals
  //0406
  wire                          txfifo_data_wr_en;
  wire [AXI_DATA_WIDTH-1 : 0]   txfifo_data_din;
  wire                          txfifo_leng_wr_en;
  wire [AXI_LIB_WIDTH-1 : 0]    txfifo_leng_din;
  wire                          txfifo_full;
  //0411
    wire                          txfifo_data_wr_en_10g;
    wire [AXI_DATA_WIDTH-1 : 0]   txfifo_data_din_10g;
    wire                          txfifo_leng_wr_en_10g;
    wire [AXI_LIB_WIDTH-1 : 0]    txfifo_leng_din_10g;
    wire                          txfifo_full_10g;
    wire                          txfifo_start_10g;
    
    wire                          txfifo_data_wr_en_40g;
    wire [AXI_DATA_WIDTH-1 : 0]   txfifo_data_din_40g;
    wire                          txfifo_leng_wr_en_40g;
    wire [AXI_LIB_WIDTH-1 : 0]    txfifo_leng_din_40g;
    wire                          txfifo_full_40g;
    wire                          txfifo_start_40g;
    
  //Write Descriptors FIFO Control
  wire                          axiw_rxdesc_fifo_rd_en ;
  wire [AXI_DATA_WIDTH-1 : 0]   axiw_rxdesc_fifo_dout  ;     
  wire                          axiw_rxdesc_fifo_empty ;
  
  wire                          axiw_txdesc_fifo_rd_en ;
  wire [AXI_DATA_WIDTH-1 : 0]   axiw_txdesc_fifo_dout  ;     
  wire                          axiw_txdesc_fifo_empty ;
  
  wire [127 : 0]                rxdesc_fifo_dout;
  wire                          rxdesc_fifo_empty;
  wire                          rxdesc_fifo_rd_en;
  wire                          rxdesc_fifo_rd_en_control;
  wire                          rxdesc_fifo_wr_en;
  wire [127 : 0]                rxdesc_fifo_din;
  wire                          rxdesc_fifo_full;

  wire [127 : 0]                txdesc_fifo_dout;
  wire                          txdesc_fifo_empty;
  wire                          txdesc_fifo_rd_en;
  wire                          txdesc_fifo_wr_en;
  wire [127 : 0]                txdesc_fifo_din;
  wire                          txdesc_fifo_full;

  //Read Descriptors FIFO Control
  wire                          axir_rxdesc_fifo_wr_en ;
  wire [DMA_DATA_WIDTH-1 : 0]   axir_rxdesc_fifo_din   ;
  wire                          axir_rxdesc_fifo_full  ;
                                                         
  wire                          axir_txdesc_fifo_wr_en ;
  wire [DMA_DATA_WIDTH-1 : 0]   axir_txdesc_fifo_din   ;
  wire                          axir_txdesc_fifo_full  ;
    
/*****************************************************/
  // IRQ

  wire                          clr_rx_error,clr_tx_error;

  wire                          rx_ioc_int;
  wire                          tx_ioc_int;

  wire                          rx_complete_int;
  wire                          tx_complete_int;

  wire                          rx_fifo_empty_check;
  reg [1:0]                     rx_mac_int_check;
  reg                           rx_mac_int_lock;
  wire                          rx_mac_int;
  wire                          tx_mac_int;

  wire                          clr_rx_complete;
  wire                          clr_tx_complete;

  reg [2:0]                     rxfifo_empty0_check;
  reg [2:0]                     rxfifo_empty1_check;

  wire                          rxfifo_timeout_valid;

/*****************************************************/
  wire [31:0]                   rxdesc_ring_length;
  wire [31:0]                   txdesc_ring_length;

  wire                          start_rx_write;
  wire                          start_tx_read;

  wire [AXI_ADDR_WIDTH-1 : 0]   rx_desc_address;
  wire [AXI_ADDR_WIDTH-1 : 0]   tx_desc_address;

  wire                          read_desc_done;
  wire                          write_desc_done;

  wire                          read_data_done;
  wire                          write_data_done;

  wire                          read_almost_done;
  wire                          write_almost_done;

  wire                          read_desc_almost_done;
  wire                          write_desc_almost_done;
  
  wire [AXI_ADDR_WIDTH-1 : 0]   rdesc_addr_current;
  wire [AXI_ADDR_WIDTH-1 : 0]   tdesc_addr_current;

  wire [2:0]                    rx_process_flag;
  wire [2:0]                    tx_process_flag;

  wire                          double_empty_flag;
  wire                          double_empty_flag_0;
  reg  [1:0]                    double_empty_flag_r;

  reg  [1:0]                    rxdesc_fifo_rd_en_state;

  wire                          rx_tail_halted;
  wire                          tx_tail_halted;
  
  always @(posedge axi_s1_clk_i or negedge axi_s1_resetn_i) begin
    if (~axi_s1_resetn_i)
      double_empty_flag_r <= 2'b11;
    else
      double_empty_flag_r <= {double_empty_flag_r[0],double_empty_flag_0};
  end

  assign double_empty_flag_0 = (dma_channel_sel_i == 2'b11) ? (dma_empty_1_i & dma_empty_0_i) : (rxfifo_empty1 & rxfifo_empty0);
  assign double_empty_flag = &double_empty_flag_r;

  //reg bus1_axi_strm_ttlast_r;
  //always @(posedge axi_s1_clk_i or negedge axi_s1_resetn_i) begin
  //  if (~axi_s1_resetn_i)
  //    bus1_axi_strm_ttlast_r <= 1'b0;
  //  else
  //    bus1_axi_strm_ttlast_r <= bus1_axi_strm_ttlast_o;
  //end
  //reg   axi_stream_data_done;
//
  //always @(posedge m_axi_aclk_i or negedge m_axi_aresetn_i) begin
  //  if (~m_axi_aresetn_i)
  //    axi_stream_data_done <= 1'b0;
  //  else
  //    axi_stream_data_done <= bus1_axi_strm_ttlast_r | bus1_axi_strm_ttlast_o | bus0_axi_strm_ttlast_o;
  //end

  // check rx fifo empty at low level,1 --> rx 10g/40g data fifo is not empty
  assign rx_fifo_empty_check = (~rxfifo_empty1_check[2] & (~rxfifo_empty1_check[1])) | (~rxfifo_empty0_check[2] & (~rxfifo_empty0_check[1]));
/*s
  always @(posedge m_axi_aclk_i or negedge m_axi_aresetn_i) begin
    if (~m_axi_aresetn_i)
      rx_mac_int_lock <= 1'b0;
    else if (~(|rx_process_flag)) // if not in rx process,should check rx data empty,to trigger rx mac int
      rx_mac_int_lock <= rx_fifo_empty_check;
    else
      rx_mac_int_lock <= 1'b0;
  end
*/
  always @(posedge m_axi_aclk_i or negedge m_axi_aresetn_i) begin
    if (~m_axi_aresetn_i)
      rx_mac_int_check <= 2'b00;
    else if (~(|rx_process_flag)) // if not in rx process,should check rx data empty,to trigger rx mac int
      rx_mac_int_check <= {rx_mac_int_check[0],rx_fifo_empty_check};
    else
      rx_mac_int_check <= 2'b00;
  end
  
  assign rx_mac_int = ~rx_mac_int_check[1] & rx_mac_int_check[0];// check rx mac interrupt at posedge
  assign tx_mac_int = 1'b0;

  // when rx timeout happened, axi master had already read 32 rdesc from main memory to axir_rxdesc_fifo. But may not use up 32 rdesc
  // because rx process is suspended unnormally, which means that if used axir_rxdesc_fifo in next rx time the left rdesc in last time 
  // will be used in this time again, so have to clear already saved but not used descriptor in rdesc fifo.
  // axir_rxdesc_fifo, axir_txdesc_fifo, axiw_rxdesc_fifo, axiw_txdesc_fifo have to remain empty while not in process.
  always @(posedge m_axi_aclk_i or negedge m_axi_aresetn_i) begin
    if (~m_axi_aresetn_i)
      rxdesc_fifo_rd_en_state <= 2'b00;
    else if (rxdesc_fifo_empty)       //timeout flag
      rxdesc_fifo_rd_en_state <= 2'b00;
    else if (rxfifo_timeout_valid)    //timeout flag
      rxdesc_fifo_rd_en_state <= 2'b01;
    else if (axiw_rxdesc_fifo_rd_en & rxdesc_fifo_rd_en_state[0])//after timeout flag, writing back rdesc
      rxdesc_fifo_rd_en_state <= 2'b10;
    else if (write_desc_done & axiw_rxdesc_fifo_empty & rxdesc_fifo_rd_en_state[1])  //writing back rdesc finished,need to clear axir_rxdesc_fifo
      rxdesc_fifo_rd_en_state <= 2'b11;
    else
      rxdesc_fifo_rd_en_state <= rxdesc_fifo_rd_en_state;
  end

  assign rxdesc_fifo_rd_en = &rxdesc_fifo_rd_en_state ? 1'b1 : rxdesc_fifo_rd_en_control;
  
  // not used temporary

  /*TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT*/
  /*-------------<Sub-module instantiation>-------------*/
  /*TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT*/
  np_dma_decode #(
    //.NP_DMA_BASE_ADDR       (NP_DMA_BASE_ADDR),
    .AXI_LIB_WIDTH          (AXI_LIB_WIDTH),
    .AXI_ADDR_WIDTH         (AXI_ADDR_WIDTH)
    )u_np_dma_decode
    (
    .dma_base_addr_i          (dma_addr), //NP_DMA_BASE_ADDR

    .hclk_i                   (HCLK),
    .hresetn_i                (HRESETn),
    .hsel_i                   (HSEL),
    .hready_i                 (HREADY),
    .htrans_i                 (HTRANS),
    .hsize_i                  (HSIZE),
    .hwrite_i                 (HWRITE),
    .haddr_i                  (HADDR),
    .hwdata_i                 (HWDATA),
    .hreadyout_o              (HREADYOUT),
    .hresp_o                  (HRESP),    
    .hrdata_o                 (HRDATA),

    .rxdesc_ring_length_o     (rxdesc_ring_length), // ahb_clk
    .txdesc_ring_length_o     (txdesc_ring_length), // ahb_clk

    .rx_desc_addr_o           (rx_desc_address),  // ahb_clk
    .tx_desc_addr_o           (tx_desc_address),  // ahb_clk

    // m_axi_aclk domain
    .m_axi_aclk_i             (m_axi_aclk_i),
    .m_axi_aresetn_i          (m_axi_aresetn_i),
    
    .rx_process_flag_i        (rx_process_flag),
    .tx_process_flag_i        (tx_process_flag),

    .rx_ioc_int_i             (rx_ioc_int),
    .tx_ioc_int_i             (tx_ioc_int),

    .rx_own_int_i             (1'b0),
    .tx_own_int_i             (1'b0),

    .rx_mac_int_i             (rx_mac_int),
    .tx_mac_int_i             (tx_mac_int),

    .rx_complete_int_i        (rx_complete_int),
    .tx_complete_int_i        (tx_complete_int),

    .rx_fifo_empty_i          (double_empty_flag),//(rxfifo_empty),  // m_axi_master

    .rdesc_addr_current_i     (rdesc_addr_current),
    .tdesc_addr_current_i     (tdesc_addr_current),

    // output
    .rx_buf_unavlib_int_clr_o (clr_rx_error),  // m_axi_master
    .tx_buf_unavlib_int_clr_o (clr_tx_error),  // m_axi_master

    .clr_rx_complete_o        (clr_rx_complete),
    .clr_tx_complete_o        (clr_tx_complete),

    .rxfifo_timeout_valid_o   (rxfifo_timeout_valid),  // m_axi_master
    .np_dma_irq_o             (np_dma_irq_o),  // m_axi_master
    
    .rx_tail_halted_o         (rx_tail_halted),
    .tx_tail_halted_o         (tx_tail_halted),

    .rx_start_o               (start_rx_write),   // m_axi_master
    .tx_start_o               (start_tx_read)     // m_axi_master
  );
  
  axi_master_interface_wrapper  #( 
    //.AXI_UNALIGN_ADDR_EN      (AXI_UNALIGN_ADDR_EN),
    .AXI_MAX_INSTR_NUM        (MAX_OUTSTANDING_NUM),
    .AXI_BURST_LEN            (AXI_BURST_LEN),
    .AXI_ID_WIDTH             (AXI_ID_WIDTH),
    .AXI_ADDR_WIDTH           (AXI_ADDR_WIDTH),
    .AXI_DATA_WIDTH           (AXI_DATA_WIDTH),
    .AXI_LIB_WIDTH            (AXI_LIB_WIDTH),
    .AXI_AWUSER_WIDTH         (AXI_AWUSER_WIDTH),
    .AXI_ARUSER_WIDTH         (AXI_ARUSER_WIDTH),
    .AXI_WUSER_WIDTH          (AXI_WUSER_WIDTH),
    .AXI_RUSER_WIDTH          (AXI_RUSER_WIDTH),
    .AXI_BUSER_WIDTH          (AXI_BUSER_WIDTH)
   ) u_axi_master_interface_wrapper (
    .m_axi_aclk_i               (m_axi_aclk_i),
    .m_axi_aresetn_i            (m_axi_aresetn_i),
    .m_axi_awid_o               (m_axi_awid_o),
    .m_axi_awaddr_o             (m_axi_awaddr_o),
    .m_axi_awlen_o              (m_axi_awlen_o),
    .m_axi_awsize_o             (m_axi_awsize_o),
    .m_axi_awburst_o            (m_axi_awburst_o),
    .m_axi_awlock_o             (m_axi_awlock_o),
    .m_axi_awcache_o            (m_axi_awcache_o),
    .m_axi_awprot_o             (m_axi_awprot_o),
    .m_axi_awqos_o              (m_axi_awqos_o),
    .m_axi_awuser_o             (m_axi_awuser_o),
    .m_axi_awvalid_o            (m_axi_awvalid_o),
    .m_axi_awready_i            (m_axi_awready_i),

    .m_axi_wdata_o              (m_axi_wdata_o),
    .m_axi_wstrb_o              (m_axi_wstrb_o),
    .m_axi_wlast_o              (m_axi_wlast_o),
    .m_axi_wuser_o              (m_axi_wuser_o),
    .m_axi_wvalid_o             (m_axi_wvalid_o),
    .m_axi_wready_i             (m_axi_wready_i),

    .m_axi_bid_i                (m_axi_bid_i),
    .m_axi_bresp_i              (m_axi_bresp_i),
    .m_axi_buser_i              (m_axi_buser_i),
    .m_axi_bvalid_i             (m_axi_bvalid_i),
    .m_axi_bready_o             (m_axi_bready_o),

    .m_axi_arid_o               (m_axi_arid_o),
    .m_axi_araddr_o             (m_axi_araddr_o),
    .m_axi_arlen_o              (m_axi_arlen_o),
    .m_axi_arsize_o             (m_axi_arsize_o),
    .m_axi_arburst_o            (m_axi_arburst_o),
    .m_axi_arlock_o             (m_axi_arlock_o),
    .m_axi_arcache_o            (m_axi_arcache_o),
    .m_axi_arprot_o             (m_axi_arprot_o),
    .m_axi_arqos_o              (m_axi_arqos_o),
    .m_axi_aruser_o             (m_axi_aruser_o),
    .m_axi_arvalid_o            (m_axi_arvalid_o),
    .m_axi_arready_i            (m_axi_arready_i),

    .m_axi_rid_i                (m_axi_rid_i),
    .m_axi_rdata_i              (m_axi_rdata_i),
    .m_axi_rresp_i              (m_axi_rresp_i),
    .m_axi_rlast_i              (m_axi_rlast_i),
    .m_axi_ruser_i              (m_axi_ruser_i),
    .m_axi_rvalid_i             (m_axi_rvalid_i),
    .m_axi_rready_o             (m_axi_rready_o),

    //******  [External Ports] Wirte Channel  ******//
    .write_id_i                 ({AXI_ID_WIDTH{1'b0}}),//  (write_id),
    .write_addr_i               (axi_aw_addr),
    .write_len_in_byte_i        (axi_w_bytes),
    .write_desc_type_i          (axi_write_desc_type),
    .write_desc_en_i            (axi_write_desc_start),
    .write_data_ready_o         (write_data_ready),
    .write_desc_ready_o         (write_desc_ready),
    .start_write_i              (axi_aw_start),

    .rxfifo_data_rd_en_o        (rxfifo_data_rd_en),
    .rxfifo_data_dout_i         (rxfifo_data_dout),
    .rxfifo_data_valid_i        (rxfifo_data_valid),
    .rxfifo_empty_i             (double_empty_flag),//(rxfifo_empty),

    .axiw_rxdesc_fifo_rd_en_o   (axiw_rxdesc_fifo_rd_en),
    .axiw_rxdesc_fifo_dout_i    (axiw_rxdesc_fifo_dout),
    .axiw_rxdesc_fifo_empty_i   (axiw_rxdesc_fifo_empty),
    
    .axiw_txdesc_fifo_rd_en_o   (axiw_txdesc_fifo_rd_en),
    .axiw_txdesc_fifo_dout_i    (axiw_txdesc_fifo_dout),
    .axiw_txdesc_fifo_empty_i   (axiw_txdesc_fifo_empty),

    //******  [External Ports] Read Channel  ******//
    .read_id_i                  ({AXI_ID_WIDTH{1'b0}}),//(read_id),
    .read_addr_i                (axi_ar_addr),
    .read_len_in_byte_i         (axi_r_bytes),
    .read_desc_type_i           (axi_read_desc_type),
    .read_desc_en_i             (axi_read_desc_start),
    .start_read_i               (axi_ar_start),
    .read_ready_o               (read_ready),
    //0406
    //.txfifo_data_wr_en_o        (txfifo_data_wr_en),
    //.txfifo_data_din_o          (txfifo_data_din),
    //.txfifo_full_i              (txfifo_full),
    //0414
    .read_data_10g40g_sel_i    (tx_port_sel),
    .txfifo_data_wr_en_40g_o   (txfifo_data_wr_en_40g),
    .txfifo_data_din_40g_o     (txfifo_data_din_40g),
    .txfifo_full_40g_i         (txfifo_full_40g),
    .txfifo_leng_wr_en_40g_o   (txfifo_leng_wr_en_40g),
    .txfifo_leng_din_40g_o     (txfifo_leng_din_40g),
    .txfifo_start_40g_o        (txfifo_start_40g),
    
    .txfifo_data_wr_en_10g_o   (txfifo_data_wr_en_10g),
    .txfifo_data_din_10g_o     (txfifo_data_din_10g),
    .txfifo_full_10g_i         (txfifo_full_10g),
    .txfifo_leng_wr_en_10g_o   (txfifo_leng_wr_en_10g),
    .txfifo_leng_din_10g_o     (txfifo_leng_din_10g),
    .txfifo_start_10g_o        (txfifo_start_10g),

    .axir_rxdesc_fifo_wr_en_o   (axir_rxdesc_fifo_wr_en),
    .axir_rxdesc_fifo_din_o     (axir_rxdesc_fifo_din  ),
    .axir_rxdesc_fifo_full_i    (axir_rxdesc_fifo_full ),
    .axir_txdesc_fifo_wr_en_o   (axir_txdesc_fifo_wr_en),
    .axir_txdesc_fifo_din_o     (axir_txdesc_fifo_din  ),
    .axir_txdesc_fifo_full_i    (axir_txdesc_fifo_full ),

    .transaction_done_pulse_o   ({read_desc_almost_done,write_desc_almost_done,read_almost_done,write_almost_done,read_desc_done, write_desc_done, read_data_done, write_data_done}),
    // not used   
    .debug_state_o              (debug_state),
		.ram_2p_cfg_register					(ram_2p_cfg_register),
		.rf_2p_cfg_register						(rf_2p_cfg_register)
  );

  np_dma_control # (
    .AXI_ADDR_WIDTH           (AXI_ADDR_WIDTH),
    .AXI_LIB_WIDTH            (AXI_LIB_WIDTH),
    .DESC_NUM                 ('d14)
    ) u_np_dma_control(
    .m_axi_aclk_i                 (m_axi_aclk_i),
    .m_axi_aresetn_i              (m_axi_aresetn_i),
    
    .rx_port_sel_i                (rx_port_sel),
    .tx_port_sel_o                (tx_port_sel),
    
    .rx_start_i                   (start_rx_write),//(1'b0),//
    .rx_desc_address_i            (rx_desc_address),

    .tx_start_i                   (start_tx_read),//(start_rx_write),//
    .tx_desc_address_i            (tx_desc_address),

    .rx_desc_fifo_rd_en_o         (rxdesc_fifo_rd_en_control),
    .rx_desc_read_i               (rxdesc_fifo_dout),
    .rx_desc_fifo_rd_empty_i      (rxdesc_fifo_empty),
    .rx_desc_fifo_wr_en_o         (rxdesc_fifo_wr_en),
    .rx_desc_wrback_o             (rxdesc_fifo_din),
    .rx_desc_fifo_wr_full_i       (rxdesc_fifo_full),

    .tx_desc_fifo_rd_en_o         (txdesc_fifo_rd_en),
    .tx_desc_read_i               (txdesc_fifo_dout),
    .tx_desc_fifo_rd_empty_i      (txdesc_fifo_empty),
    .tx_desc_fifo_wr_en_o         (txdesc_fifo_wr_en),
    .tx_desc_wrback_o             (txdesc_fifo_din),
    .tx_desc_fifo_wr_full_i       (txdesc_fifo_full),

    .rxfifo_length_rd_en_o    (rxfifo_leng_rd_en),
    .rxfifo_length_dout_i     (rxfifo_leng_dout),
    .rxfifo_empty_i           (double_empty_flag),//(rxfifo_empty),

    .txfifo_length_wr_en_o    (txfifo_leng_wr_en),
    .txfifo_length_dout_o     (txfifo_leng_din),
    .txfifo_full_i            (txfifo_full_40g | txfifo_full_10g),//(txfifo_full),

    .axi_aw_addr_o            (axi_aw_addr),
    .axi_w_bytes_o            (axi_w_bytes),
    .axi_aw_start_o           (axi_aw_start),
    .axi_write_desc_type_o    (axi_write_desc_type),
    .axi_write_desc_start_o   (axi_write_desc_start),
    .write_desc_ready_i       (write_desc_ready),
    .write_data_ready_i       (write_data_ready),

    .axi_ar_addr_o            (axi_ar_addr),
    .axi_r_bytes_o            (axi_r_bytes),
    .axi_ar_start_o           (axi_ar_start),
    .axi_read_desc_type_o     (axi_read_desc_type),
    .axi_read_desc_start_o    (axi_read_desc_start),
    .read_ready_i             (read_ready),
    
    .rxfifo_timeout_valid_i   (rxfifo_timeout_valid),

    .write_almost_done_i      (write_almost_done),
    .write_already_done_i     (write_data_done),
    .read_almost_done_i       (read_almost_done),
    .read_already_done_i      (read_data_done),
    .read_desc_done_i         (read_desc_done),
    .write_desc_done_i        (write_desc_done),
    //.axi_stream_data_done_i   (axi_stream_data_done),

    .rx_process_flag_o        (rx_process_flag),
    .tx_process_flag_o        (tx_process_flag),

    .rx_ioc_int_o             (rx_ioc_int),
    .tx_ioc_int_o             (tx_ioc_int),

    .rx_complete_int_o        (rx_complete_int),
    .tx_complete_int_o        (tx_complete_int),
    
    .clr_rx_complete_i        (clr_rx_complete),
    .clr_tx_complete_i        (clr_tx_complete),

    .rdesc_addr_current_o     (rdesc_addr_current),
    .tdesc_addr_current_o     (tdesc_addr_current),

    .rx_tail_halted_i         (rx_tail_halted),
    .tx_tail_halted_i         (tx_tail_halted),

    .rx_desc_num_i            (rxdesc_ring_length),
    .tx_desc_num_i            (txdesc_ring_length)

  );

  //***************************************************************************
  //                           RxFIFO
  //***************************************************************************

  wire  rxfifo_data_empty0;
  wire  rxfifo_data_empty1;

  np_dma_rx_data  #(
        .DMA_DWIDTH   (128), // DMA Data Width
        .LEN_DWIDTH   (AXI_LIB_WIDTH)  // LEN Data Width
   ) u_np_dma_rx_data(
    .clk_i                            (m_axi_aclk_i),
    .resetn_i                         (m_axi_aresetn_i),

    .almost_done_i                    (write_almost_done),
    .already_done_i                   (write_data_done),

    .rxfifo_rd_data0_en_o             (rxfifo_data0_rd_en),
    .rxfifo_rd_dout0_i                (rxfifo_data0_dout),
    .rxfifo_empty0_i                  (rxfifo_empty0),
    .rxfifo_data_empty0_i             (rxfifo_data_empty0),
    .rxfifo_rd_leng0_en_o             (rxfifo_leng0_rd_en),
    .rxfifo_rd_leng0_i                (rxfifo_leng0_dout),

    .rxfifo_rd_data1_en_o             (rxfifo_data1_rd_en),
    .rxfifo_rd_dout1_i                (rxfifo_data1_dout),
    .rxfifo_empty1_i                  (rxfifo_empty1),
    .rxfifo_data_empty1_i             (rxfifo_data_empty1),
    .rxfifo_rd_leng1_en_o             (rxfifo_leng1_rd_en),
    .rxfifo_rd_leng1_i                (rxfifo_leng1_dout),

    .rxfifo_rd_data_en_i              (rxfifo_data_rd_en),
    .rxfifo_rd_dout_o                 (rxfifo_data_dout),
	  .rxfifo_rd_dout_vld_o             (rxfifo_data_valid),
    .rxfifo_empty_o                   (rxfifo_empty),
    .rxfifo_rd_leng_en_i              (rxfifo_leng_rd_en),
    .rxfifo_rd_leng_o                 (rxfifo_leng_dout),

    .port_sel_o                       (rx_port_sel),
    //05.03 zyc
    .cpt_rd_leng_en_0_o               (dma_rd_leng_en_0_o ),
	  .cpt_rd_data_en_0_o               (dma_rd_data_en_0_o ),
	  .cpt_rd_leng_vld_0_i              (dma_rd_leng_vld_0_i),
	  .cpt_rd_dout_vld_0_i              (dma_rd_dout_vld_0_i),
	  .cpt_rd_leng_0_i                  (dma_rd_leng_0_i    ),
	  .cpt_rd_dout_0_i                  (dma_rd_dout_0_i    ),
	  .cpt_empty_0_i                    (dma_empty_0_i      ),
    .cpt_data_empty_0_i               (dma_data_empty_0_i ), //05.21 zyc
	
    .cpt_rd_leng_en_1_o               (dma_rd_leng_en_1_o ),
    .cpt_rd_data_en_1_o               (dma_rd_data_en_1_o ),
    .cpt_rd_leng_vld_1_i              (dma_rd_leng_vld_1_i),
    .cpt_rd_dout_vld_1_i              (dma_rd_dout_vld_1_i),
    .cpt_rd_leng_1_i                  (dma_rd_leng_1_i    ),
    .cpt_rd_dout_1_i                  (dma_rd_dout_1_i    ),
    .cpt_empty_1_i                    (dma_empty_1_i      ),
    .cpt_data_empty_1_i               (dma_data_empty_1_i ),

    .rxfifo_cpt_sel_i                 (dma_channel_sel_i),
    .data_sel_lock_i                  (debug_state[2])
    
  );

  axi_write_channel_rxfifo_10g #(
    .MAC_DWIDTH              (MAC_DATA_WIDTH),
    .MAC_KWIDTH              (MAC_KEEP_WIDTH),
    .MAC_KBITS               (MAC_KEEP_CNT_WIDTH), //7->3bits
    .MAC_UWIDTH              (MAC_USER_WIDTH),
    .DMA_DWIDTH              (128),    //    -----(DMA_DATA_WIDTH),
    .LEN_DWIDTH              (11),     //    -----(DMA_LENG_WIDTH),
    .MEM_AWIDTH              (DMA_DATA_FIFO_rx_10g_AW),     //4096-----(DMA_DATA_FIFO_AW),
    .LEN_AWIDTH              (DMA_LENG_FIFO_rx_10g_AW)      //1024-----(DMA_LENG_FIFO_AW)
    ) u_axi_write_channel_rxfifo_10g (
    .wclk                    (axi_s0_clk_i),
    .rclk                    (m_axi_aclk_i),
    //.arstn                   (axi_s0_resetn_i),//(m_axi_aresetn_i),
    .rstn_wclk               (axi_s0_resetn_i),
    .rstn_rclk               (m_axi_aresetn_i),
    .s_axis_tvalid_i         (bus0_axi_strm_rtvalid_i),
    .s_axis_tlast_i          (bus0_axi_strm_rtlast_i),
    .s_axis_tkeep_i          (bus0_axi_strm_rtkeep_i),
    .s_axis_tdata_i          (bus0_axi_strm_rtdata_i),
    .s_axis_tready_o         (bus0_axi_strm_rtready_o),
    .s_axis_tuser_i          ({MAC_USER_WIDTH{1'b0}}),//(bus0_axi_strm_rtuser_i[3:0]),

    .rd_leng_en_i            (rxfifo_leng0_rd_en),
    .rd_leng_o               (rxfifo_leng0_dout),

    .rd_data_en_i            (rxfifo_data0_rd_en),
    .rd_dout_o               (rxfifo_data0_dout),
    .empty_o                 (rxfifo_empty0),
    .data_empty_o            (rxfifo_data_empty0),
    .ram_dp_cfg_register     (ram_dp_cfg_register),
    .mbist_test              (mbist_test)
  );

  always @(posedge m_axi_aclk_i or negedge m_axi_aresetn_i) begin
    if(~m_axi_aresetn_i) begin
      rxfifo_empty0_check <= 3'b111;
    end
    else if(dma_channel_sel_i == 2'b11) begin
      rxfifo_empty0_check <= {rxfifo_empty0_check[1:0],dma_empty_0_i};
    end
    else begin
      rxfifo_empty0_check <= {rxfifo_empty0_check[1:0],rxfifo_empty0};
    end
  end

  axi_write_channel_rxfifo_40g #(
    .MAC_DWIDTH              (MAC_DATA_WIDTH),
    .MAC_KWIDTH              (MAC_KEEP_WIDTH),
    .MAC_KBITS               (MAC_KEEP_CNT_WIDTH), //7->3bits
    .MAC_UWIDTH              (MAC_USER_WIDTH),
    .DMA_DWIDTH              (128),    //     -----(DMA_DATA_WIDTH),
    .LEN_DWIDTH              (11),     //     -----(DMA_LENG_WIDTH),
    .MEM_AWIDTH              (DMA_DATA_FIFO_rx_40g_AW),     //16384-----(DMA_DATA_FIFO_AW),
    .LEN_AWIDTH              (DMA_LENG_FIFO_rx_40g_AW)      //4096 -----(DMA_LENG_FIFO_AW)
    ) u_axi_write_channel_rxfifo_40g (
    .wclk                    (axi_s1_clk_i),
    .rclk                    (m_axi_aclk_i),
    //.arstn                   (axi_s1_resetn_i),//(m_axi_aresetn_i),
    .rstn_wclk               (axi_s1_resetn_i),
    .rstn_rclk               (m_axi_aresetn_i),
    .s_axis_tvalid_i         (bus1_axi_strm_rtvalid_i),
    .s_axis_tlast_i          (bus1_axi_strm_rtlast_i),
    .s_axis_tkeep_i          (bus1_axi_strm_rtkeep_i),
    .s_axis_tdata_i          (bus1_axi_strm_rtdata_i),
    .s_axis_tready_o         (bus1_axi_strm_rtready_o),
    .s_axis_tuser_i          ({MAC_USER_WIDTH{1'b0}}),//(bus1_axi_strm_rtuser_i[3:0]),

    .rd_leng_en_i            (rxfifo_leng1_rd_en),
    .rd_leng_o               (rxfifo_leng1_dout),

    .rd_data_en_i            (rxfifo_data1_rd_en),
    .rd_dout_o               (rxfifo_data1_dout),
    .empty_o                 (rxfifo_empty1),
    .data_empty_o            (rxfifo_data_empty1),
    .ram_dp_cfg_register     (ram_dp_cfg_register),
    .mbist_test              (mbist_test)
  );

  always @(posedge m_axi_aclk_i or negedge m_axi_aresetn_i) begin
    if(~m_axi_aresetn_i) begin
      rxfifo_empty1_check <= 3'b111;
    end
    else if(dma_channel_sel_i == 2'b11) begin
      rxfifo_empty1_check <= {rxfifo_empty1_check[1:0],dma_empty_1_i};
    end
    else begin
      rxfifo_empty1_check <= {rxfifo_empty1_check[1:0],rxfifo_empty1};
    end
  end

  //***************************************************************************
  //                           TxFIFO
  //***************************************************************************

  axi_read_channel_txfifo # (
      .MAC_UWIDTH              (MAC_USER_WIDTH),
      .DMA_DWIDTH              (128),
      .LEN_DWIDTH              (11),
      .MEM_AWIDTH_10g              (DMA_DATA_FIFO_tx_10g_AW),      //2048-----(DMA_DATA_FIFO_AW),
      .LEN_AWIDTH_10g              (DMA_LENG_FIFO_tx_10g_AW),      //512 -----(DMA_LENG_FIFO_AW),
      .MEM_AWIDTH_40g              (DMA_DATA_FIFO_tx_40g_AW),      //512 -----(DMA_DATA_FIFO_AW),
      .LEN_AWIDTH_40g              (DMA_LENG_FIFO_tx_40g_AW)       //128 -----(DMA_LENG_FIFO_AW)
    )
    txfifo_axi_read_channel
    (
      .wclk_10g                    (m_axi_aclk_i),
      .rstn_wclk_10g               (m_axi_aresetn_i),
      .start_i_10g                 (txfifo_start_10g),
      .wr_data_en_i_10g            (txfifo_data_wr_en_10g),
      .wr_leng_en_i_10g            (txfifo_leng_wr_en_10g),
      .wr_data_i_10g               (txfifo_data_din_10g),
      .wr_leng_i_10g               (txfifo_leng_din_10g),
      .wr_full_o_10g               (txfifo_full_10g),

      //AXI-Stream OUTPUT to MAC
      .rclk_10g                    (axi_s0_clk_i),
      .rstn_rclk_10g               (axi_s0_resetn_i),
      .m_axis_tvalid_o_10g         (bus0_axi_strm_ttvalid_o),
      .m_axis_tlast_o_10g          (bus0_axi_strm_ttlast_o),
      .m_axis_tkeep_o_10g          (bus0_axi_strm_ttkeep_o),
      .m_axis_tdata_o_10g          (bus0_axi_strm_ttdata_o),
      .m_axis_tready_i_10g         (bus0_axi_strm_ttready_i),
      .m_axis_tuser_o_10g          (),//(bus0_axi_strm_ttuser_o),
      
      .wclk_40g                    (m_axi_aclk_i),
      .rstn_wclk_40g               (m_axi_aresetn_i),
      .start_i_40g                 (txfifo_start_40g),
      .wr_data_en_i_40g            (txfifo_data_wr_en_40g),
      .wr_leng_en_i_40g            (txfifo_leng_wr_en_40g),
      .wr_data_i_40g               (txfifo_data_din_40g),
      .wr_leng_i_40g               (txfifo_leng_din_40g),
      .wr_full_o_40g               (txfifo_full_40g),
      
      //AXI-Stream OUTPUT to MAC
      .rclk_40g                    (axi_s1_clk_i),
      .rstn_rclk_40g               (axi_s1_resetn_i),
      .m_axis_tvalid_o_40g         (bus1_axi_strm_ttvalid_o),
      .m_axis_tlast_o_40g          (bus1_axi_strm_ttlast_o),
      .m_axis_tkeep_o_40g          (bus1_axi_strm_ttkeep_o),
      .m_axis_tdata_o_40g          (bus1_axi_strm_ttdata_o),
      .m_axis_tready_i_40g         (bus1_axi_strm_ttready_i),
      .m_axis_tuser_o_40g          (),//(bus1_axi_strm_ttuser_o),
      .ram_dp_cfg_register    		 (ram_dp_cfg_register)
  );
  /*0406
  axi_read_channel_txfifo #(
    .MAC_UWIDTH              (90),
    .DMA_DWIDTH              (DMA_DATA_WIDTH),
    .MEM_AWIDTH              (DMA_DATA_FIFO_AW),
    .LEN_DWIDTH              (DMA_LENG_WIDTH),
    .LEN_AWIDTH              (DMA_LENG_FIFO_AW)
    ) u_axi_read_channel_txfifo (
    .wclk                    (m_axi_aclk_i),
    .rclk                    (axi_s1_clk_i),
    .arstn                   (m_axi_aresetn_i),

    .start_i                 (read_data_done),

    .wr_data_en_i            (txfifo_data_wr_en),
    .wr_leng_en_i            (txfifo_leng_wr_en),
    .wr_data_i               (txfifo_data_din),
    .wr_leng_i               (txfifo_leng_din),
    .wr_full_o               (txfifo_full),
    
    .m_axis_tvalid_o         (bus1_axi_strm_ttvalid_o),
    .m_axis_tlast_o          (bus1_axi_strm_ttlast_o),
    .m_axis_tkeep_o          (bus1_axi_strm_ttkeep_o),
    .m_axis_tdata_o          (bus1_axi_strm_ttdata_o),
    .m_axis_tready_i         (bus1_axi_strm_ttready_i),
    .m_axis_tuser_o          (bus1_axi_strm_ttuser_o)
  );
  */

  //***************************************************************************
  //                           Write Descriptors FIFO
  //***************************************************************************

`ifdef VCS_MODEL
  axi_sfifo_2T # (
    .DW                      (DMA_DATA_WIDTH),
    .AW                      (DMA_DESC_FIFO_wr_AW)
    ) u_axiw_rxdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From DMA Control***/
    .wr_en                   (rxdesc_fifo_wr_en),
    .din                     (rxdesc_fifo_din),
    .full                    (rxdesc_fifo_full),
    .almost_full             (),
    
    /*** To AXI Master Interface ***/
    .rd_en                   (axiw_rxdesc_fifo_rd_en),   
    .dout                    (axiw_rxdesc_fifo_dout),   
    .empty                   (axiw_rxdesc_fifo_empty)
  );
  
  axi_sfifo_2T # (
    .DW                      (DMA_DATA_WIDTH),
    .AW                      (DMA_DESC_FIFO_wr_AW)
    ) u_axiw_txdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From DMA Control***/
    .wr_en                   (txdesc_fifo_wr_en),
    .din                     (txdesc_fifo_din),
    .full                    (txdesc_fifo_full),
    .almost_full             (),   
                                   
    /*** To AXI Master Interface ***/
    .rd_en                   (axiw_txdesc_fifo_rd_en),   
    .dout                    (axiw_txdesc_fifo_dout),   
    .empty                   (axiw_txdesc_fifo_empty)
  );
  
  //***************************************************************************
  //                           Read Descriptors FIFO
  //***************************************************************************
  axi_sfifo_2T # (
    .DW                      (DMA_DATA_WIDTH),
    .AW                      (DMA_DESC_FIFO_rd_AW)
    ) u_axir_rxdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From AXI Master Interface ***/
    .wr_en                   (axir_rxdesc_fifo_wr_en),
    .din                     (axir_rxdesc_fifo_din),
    .full                    (axir_rxdesc_fifo_full),
    .almost_full             (),
    
    /*** To DMA Control***/
    .rd_en                   (rxdesc_fifo_rd_en),
    .dout                    (rxdesc_fifo_dout),
    .empty                   (rxdesc_fifo_empty)
  );
  
  axi_sfifo_2T # (
    .DW                      (DMA_DATA_WIDTH),
    .AW                      (DMA_DESC_FIFO_rd_AW)
    ) u_axir_txdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From AXI Master Interface ***/
    .wr_en                   (axir_txdesc_fifo_wr_en),
    .din                     (axir_txdesc_fifo_din),
    .full                    (axir_txdesc_fifo_full),
    .almost_full             (),
    
    /*** To DMA Control***/
    .rd_en                   (txdesc_fifo_rd_en),
    .dout                    (txdesc_fifo_dout),
    .empty                   (txdesc_fifo_empty)
  );
`else
  sync_fifo_d64_w128 u_axiw_rxdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From DMA Control***/
    .wr_en                   (rxdesc_fifo_wr_en),
    .din                     (rxdesc_fifo_din),
    .full                    (rxdesc_fifo_full),
    .almost_full             (),
    
    /*** To AXI Master Interface ***/
    .rd_en                   (axiw_rxdesc_fifo_rd_en),   
    .dout                    (axiw_rxdesc_fifo_dout),   
    .empty                   (axiw_rxdesc_fifo_empty),
    .ram_2p_cfg_register     (ram_2p_cfg_register)
  );
  
  sync_fifo_d64_w128 u_axiw_txdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From DMA Control***/
    .wr_en                   (txdesc_fifo_wr_en),
    .din                     (txdesc_fifo_din),
    .full                    (txdesc_fifo_full),
    .almost_full             (),   
                                   
    /*** To AXI Master Interface ***/
    .rd_en                   (axiw_txdesc_fifo_rd_en),   
    .dout                    (axiw_txdesc_fifo_dout),   
    .empty                   (axiw_txdesc_fifo_empty),
    .ram_2p_cfg_register     (ram_2p_cfg_register)
  );
  
  //***************************************************************************
  //                           Read Descriptors FIFO
  //***************************************************************************
  sync_fifo_d64_w128 u_axir_rxdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From AXI Master Interface ***/
    .wr_en                   (axir_rxdesc_fifo_wr_en),
    .din                     (axir_rxdesc_fifo_din),
    .full                    (axir_rxdesc_fifo_full),
    .almost_full             (),
    
    /*** To DMA Control***/
    .rd_en                   (rxdesc_fifo_rd_en),
    .dout                    (rxdesc_fifo_dout),
    .empty                   (rxdesc_fifo_empty),
    .ram_2p_cfg_register     (ram_2p_cfg_register)
  );
  
  sync_fifo_d64_w128 u_axir_txdesc_fifo
    (
    .clk                     (m_axi_aclk_i),
    .rstn                    (m_axi_aresetn_i),
    
    /*** From AXI Master Interface ***/
    .wr_en                   (axir_txdesc_fifo_wr_en),
    .din                     (axir_txdesc_fifo_din),
    .full                    (axir_txdesc_fifo_full),
    .almost_full             (),
    
    /*** To DMA Control***/
    .rd_en                   (txdesc_fifo_rd_en),
    .dout                    (txdesc_fifo_dout),
    .empty                   (txdesc_fifo_empty),
    .ram_2p_cfg_register     (ram_2p_cfg_register)
  );
`endif

endmodule
